#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
视频拼接工具主窗口
提供图形界面用于导入视频、标记片段和导出结果
"""

import os
import sys
from dataclasses import dataclass
from enum import Enum
from typing import Optional, Tuple

from PySide6.QtCore import Qt, QTimer
from PySide6.QtGui import QImage, QPixmap, QColor
from PySide6.QtWidgets import (QApplication, QFileDialog, QHBoxLayout, QLabel,
                               QMainWindow, QPushButton, QSlider, QVBoxLayout,
                               QWidget, QMessageBox, QListWidget, QListWidgetItem,
                               QButtonGroup, QRadioButton, QProgressDialog)

# 导入项目模块
from src.config import Config
from src.video.video_processor import VideoProcessor
from src.video.segment_manager import SegmentManager, SegmentType
from src.video.video_exporter import VideoExporter
from src.video.ffmpeg_player import FFmpegPlayer
from src.gui.frame_handler import FrameHandler
from src.gui.time_handler import TimeHandler
from src.gui.segment_list_handler import SegmentListHandler
from src.gui.window_event_handler import WindowEventHandler

# 导入UI组件模块
from src.gui.video_preview_area import VideoPreviewArea
from src.gui.control_panel import ControlPanel
from src.gui.timeline_area import TimelineArea
from src.gui.mark_mode_area import MarkModeArea
from src.gui.segment_list_area import SegmentListArea
from src.gui.video_list_area import VideoListArea
from src.gui.video_functions import VideoFunctions
from src.gui.video_controls import VideoControls
from src.gui.slider_controls import SliderControls
from src.gui.signal_connector import SignalConnector


class VideoStitcherMainWindow(QMainWindow):
    """
    视频拼接工具主窗口类
    
    这是视频拼接工具的主界面类，继承自QMainWindow。它提供了完整的GUI界面，
    包括视频预览、播放控制、时间轴、片段标记和导出功能。
    
    该类整合了VideoProcessor、SegmentManager和VideoExporter三个核心模块，
    实现了视频编辑的完整工作流程。
    
    Attributes:
        video_processor (VideoProcessor): 视频处理实例，负责视频加载和帧提取
        segment_manager (SegmentManager): 片段管理实例，负责片段标记和管理
        video_exporter (VideoExporter): 视频导出实例，负责视频拼接和导出
        current_frame_pixmap (QPixmap): 当前帧的像素图
        cap (cv2.VideoCapture): OpenCV视频捕获对象
        timer (QTimer): 播放定时器
        is_playing (bool): 播放状态标志
        current_time (float): 当前播放时间（秒）
    """

    def __init__(self):
        """
        初始化主窗口
        
        创建主窗口并初始化所有必要的组件，包括：
        1. 核心处理模块实例化
        2. 用户界面初始化
        3. 信号槽连接
        """
        super().__init__()
        
        # 初始化变量
        self.video_processor = VideoProcessor()
        self.segment_manager = SegmentManager()
        self.video_exporter = VideoExporter()
        self.ffmpeg_player = FFmpegPlayer()  # FFmpeg播放器
        self.current_frame_pixmap = None
        self.is_playing = False
        self.selected_video_files = []  # 存储选中的视频文件列表
        
        # 初始化UI模块
        self.video_preview_area = VideoPreviewArea()
        self.control_panel = ControlPanel()
        self.timeline_area = TimelineArea()
        self.mark_mode_area = MarkModeArea()
        self.segment_list_area = SegmentListArea()
        self.video_list_area = VideoListArea(self)  # 传递主窗口引用
        self.signal_connector = SignalConnector()# 初始化各个功能模块
        self.video_functions = VideoFunctions()
        self.video_controls = VideoControls()
        self.slider_controls = SliderControls()
        self.frame_handler = FrameHandler()
        self.time_handler = TimeHandler()
        self.segment_list_handler = SegmentListHandler()
        self.window_event_handler = WindowEventHandler()
        
        # 初始化UI
        self.init_ui()
        
        # 连接信号槽
        self.connect_signals()

    def init_ui(self):
        """
        初始化用户界面
        
        设置主窗口的基本属性并创建所有UI组件。按照从上到下的顺序创建各个功能区域：
        1. 视频预览区域 - 显示视频帧
        2. 控制面板 - 播放控制按钮
        3. 时间轴区域 - 进度滑块和时间显示
        4. 标记模式选择区域 - 保留/删除模式切换
        5. 片段列表区域 - 已标记片段显示和管理
        
        Note:
            - 窗口标题设置为"VideoStitcher 视频拼接工具"
            - 默认窗口大小为1200x800，位置在屏幕(100, 100)
            - 使用垂直布局管理器组织各功能区域
            - 各功能区域通过专门的方法创建以保持代码清晰
        """
        self.setWindowTitle(Config.WINDOW_TITLE)
        self.setGeometry(Config.WINDOW_X, Config.WINDOW_Y, Config.WINDOW_WIDTH, Config.WINDOW_HEIGHT)
        
        # 创建中央部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 创建主布局（水平布局）
        main_layout = QHBoxLayout(central_widget)
        
        # 创建左侧视频列表区域
        left_widget = QWidget()
        left_layout = QVBoxLayout(left_widget)
        (_, self.video_list_widget) = self.video_list_area.create_video_list_area(left_layout)
        
        # 创建右侧内容区域
        right_widget = QWidget()
        right_layout = QVBoxLayout(right_widget)
        
        # 创建视频预览区域
        self.video_preview_area.create_video_preview_area(right_layout)
        self.video_label = self.video_preview_area.video_label
        
        # 创建控制面板
        (control_group, self.import_button, self.switch_video_button, self.play_pause_button, 
         self.skip_to_start_button, self.step_backward_button, self.step_forward_button, self.skip_to_end_button,
         self.mark_in_button, self.mark_out_button, self.export_button) = self.control_panel.create_control_panel(right_layout)
        
        # 创建时间轴区域
        (_, self.time_label, self.progress_slider) = self.timeline_area.create_timeline_area(right_layout)
        
        # 创建标记模式选择区域
        (_, self.mode_button_group, self.keep_mode_radio, self.delete_mode_radio) = self.mark_mode_area.create_mark_mode_area(right_layout)
        
        # 创建片段列表区域
        (_, self.segment_list_label, self.segment_list_widget, 
         self.delete_segment_button, self.clear_segments_button) = self.segment_list_area.create_segment_list_area(right_layout)
        
        # 将左侧和右侧区域添加到主布局
        main_layout.addWidget(left_widget, 1)  # 左侧占1份
        main_layout.addWidget(right_widget, 3)  # 右侧占3份



    def connect_signals(self):
        """
        连接信号和槽
        
        将UI组件的信号与相应的处理槽函数连接起来，包括：
        1. 按钮点击信号 - 连接到对应的处理方法
        2. 滑块操作信号 - 连接到进度控制方法
        3. 模式选择信号 - 连接到模式切换方法
        4. 定时器超时信号 - 连接到帧更新方法
        
        Note:
            - 所有按钮的clicked信号都连接到对应的处理方法
            - 滑块的sliderPressed、sliderReleased和valueChanged信号分别连接到不同的处理方法
            - 模式选择按钮组的buttonClicked信号连接到change_mark_mode方法
            - 定时器的timeout信号连接到update_frame方法，用于视频播放时的帧更新
        """
        # 使用信号连接器连接所有信号
        self.signal_connector.connect_signals(self)

    def import_video(self):
        """
        导入视频文件
        
        调用视频功能模块的import_video方法处理视频导入逻辑。
        """
        self.video_functions.import_video(self)
        
        # 如果导入了多个视频，显示切换视频按钮
        if len(self.selected_video_files) > 1:
            self.switch_video_button.setVisible(True)
            self.switch_video_button.setText(f"切换视频 (1/{len(self.selected_video_files)})")
        else:
            self.switch_video_button.setVisible(False)

    def switch_video(self):
        """
        切换到下一个视频文件
        
        调用视频功能模块的switch_video方法处理视频切换逻辑。
        """
        self.video_functions.switch_video(self)

    def toggle_play_pause(self):
        """
        切换播放/暂停状态
        
        调用视频功能模块的toggle_play_pause方法处理播放/暂停逻辑。
        """
        self.video_functions.toggle_play_pause(self)

    def skip_to_start(self):
        """
        跳转到视频开始
        
        调用视频控制模块的skip_to_start方法处理跳转逻辑。
        """
        self.video_controls.skip_to_start(self)

    def step_backward(self):
        """
        后退一帧
        
        调用视频控制模块的step_backward方法处理后退逻辑。
        """
        self.video_controls.step_backward(self)

    def step_forward(self):
        """
        前进一帧
        
        调用视频控制模块的step_forward方法处理前进逻辑。
        """
        self.video_controls.step_forward(self)

    def skip_to_end(self):
        """
        跳转到视频结束
        
        调用视频控制模块的skip_to_end方法处理跳转逻辑。
        """
        self.video_controls.skip_to_end(self)

    def mark_in_point(self):
        """
        标记入点
        
        调用视频控制模块的mark_in_point方法处理标记逻辑。
        """
        self.video_controls.mark_in_point(self)

    def mark_out_point(self):
        """
        标记出点
        
        调用视频控制模块的mark_out_point方法处理标记逻辑。
        """
        self.video_controls.mark_out_point(self)

    def export_video(self):
        """
        导出视频
        
        调用视频控制模块的export_video方法处理导出逻辑。
        """
        self.video_controls.export_video(self)

    def delete_selected_segment(self):
        """
        删除选中的片段
        
        调用视频控制模块的delete_selected_segment方法处理删除逻辑。
        """
        self.video_controls.delete_selected_segment(self)

    def clear_all_segments(self):
        """
        清空所有片段
        
        调用视频控制模块的clear_all_segments方法处理清空逻辑。
        """
        self.video_controls.clear_all_segments(self)

    def on_slider_pressed(self):
        """
        滑块按下事件
        
        调用滑块控制模块的on_slider_pressed方法处理滑块按下逻辑。
        """
        self.slider_controls.on_slider_pressed(self)

    def on_slider_released(self):
        """
        滑块释放事件
        
        调用滑块控制模块的on_slider_released方法处理滑块释放逻辑。
        """
        self.slider_controls.on_slider_released(self)

    def on_slider_value_changed(self, value):
        """
        滑块值改变事件
        
        调用滑块控制模块的on_slider_value_changed方法处理滑块值改变逻辑。
        """
        self.slider_controls.on_slider_value_changed(self, value)

    def change_mark_mode(self, button):
        """改变标记模式"""
        mode_id = self.mode_button_group.id(button)
        segment_type = SegmentType.KEEP if mode_id == 1 else SegmentType.DELETE
        self.segment_manager.set_mode(segment_type)
        mode_text = "保留" if mode_id == 1 else "删除"
        print(f"切换到{mode_text}模式")
    
    def enable_controls(self, enable):
        """
        启用或禁用视频控制按钮
        
        根据视频加载状态启用或禁用视频控制按钮。
        
        Args:
            enable (bool): True启用按钮，False禁用按钮
        """
        self.play_pause_button.setEnabled(enable)
        self.skip_to_start_button.setEnabled(enable)
        self.step_backward_button.setEnabled(enable)
        self.step_forward_button.setEnabled(enable)
        self.skip_to_end_button.setEnabled(enable)
        self.mark_in_button.setEnabled(enable)
        self.mark_out_button.setEnabled(enable)
        self.export_button.setEnabled(enable)
        
        # 如果有多个视频，启用切换视频按钮
        if enable and len(self.selected_video_files) > 1:
            self.switch_video_button.setEnabled(True)
        else:
            self.switch_video_button.setEnabled(False)

    def update_frame(self):
        """
        更新视频帧（定时器回调）
        
        调用帧处理模块的update_frame方法处理帧更新逻辑。
        """
        self.frame_handler.update_frame(self)

    def show_frame_at_time(self, time_seconds: float):
        """
        在指定时间点显示视频帧
        
        调用帧处理模块的show_frame_at_time方法处理帧显示逻辑。
        """
        self.frame_handler.show_frame_at_time(self, time_seconds)

    def update_time_display(self, current_time: float, total_time: float):
        """
        更新时间显示
        
        调用时间处理器模块的update_time_display方法处理时间显示逻辑。
        """
        self.time_handler.update_time_display(self, current_time, total_time)

    def format_time(self, seconds: float) -> str:
        """
        格式化时间为 HH:MM:SS 格式
        
        调用时间处理器模块的format_time方法处理时间格式化逻辑。
        """
        return self.time_handler.format_time(seconds)

    def update_segment_list(self):
        """
        更新片段列表显示
        
        调用片段列表处理器模块的update_segment_list方法处理片段列表显示逻辑。
        """
        self.segment_list_handler.update_segment_list(self)

    def closeEvent(self, event):
        """
        窗口关闭事件
        
        调用窗口事件处理器模块的closeEvent方法处理窗口关闭逻辑。
        """
        self.window_event_handler.closeEvent(self, event)